#include "RegisterBlock.h"

#include <string>

RegisterBlock::RegisterBlock() {
	init();
}

void RegisterBlock::init() {
	_count 	= 0;
	_size 	= REGISTER_BLOCK_MAX_SIZE;

	for ( size_t i=0; i<_size; ++i )
		valid[i] = false;
}

const DBRegister* RegisterBlock::get(std::string &name) {

	DBRegister *reg = NULL;

	for ( size_t i=0; i<_size; i++ ) {
		/* busqueda secuencial en el register block */
		if ( valid[i] && name == regs[i].name )
			return &(regs[i]);
	}

	return reg;
}

int RegisterBlock::add(const DBRegister* reg) {

	int result = -1;

	if ( reg != NULL && _count < _size ) {
		/* encontrar el primer lugar libre */
		for ( size_t i=0; i<_size; ++i ) {
			if ( ! valid[i] ) {
				valid[i] = true;
				regs[i]	 = (*reg);
				++_count;
				return i;
			}
		}
	}

	return result;
}

int RegisterBlock::remove(const DBRegister* reg) {

	int result = -1;

	if ( reg != NULL ) {

		/* si encuentro el registro -> lo invalido */
		for ( size_t i=0; i<_size; ++i ) {
			if ( valid[i] && regs[i] == *reg) {
				valid[i] = false;
				--_count;
				return i;
			}
		}
	}

	return result;
}

int RegisterBlock::update(const DBRegister* reg) {

	int result = -1;

	if ( reg != NULL ) {

		/* si encuentro el registro -> lo actualizo */
		for ( size_t i=0; i<_size; ++i ) {
			if ( valid[i] && regs[i] == *reg) {
				regs[i] = *reg;
				return i;
			}
		}
	}

	return result;
}

int RegisterBlock::load(int fd) {

	_count = 0;
	int bytes = 0;
	const int block_size = sizeof(DBRegister);

	/* leo todos los registros y los guardo en el register block */
	while ( _count < _size &&
			(bytes = read ( fd, &regs[_count], block_size )) == block_size) {

		valid[_count] = true;
		regs[_count].print();
		++_count;
	}

	/* si hubo error o eof devuelvo -1 */
	if ( bytes != block_size )
		bytes = -1;

	return bytes;
}

void RegisterBlock::save(int fd) {

	int bytes = 0;
	size_t count = 0;
	size_t saved = 0;
	const int block_size = sizeof(DBRegister);

	/* leo todos los registros y los guardo en el register block */
	while ( count < _size ) {

		/* si el registro es valido lo escribo */
		if ( valid[count] ) {
			bytes = write ( fd, &regs[count], block_size );
			++ saved;
		}
		++count;
	}
	std::clog<< " *** Escritos "<< saved <<" registros en la base de datos ***"<<std::endl;
}


